package com.david.IfaceAutoTest.utils;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.david.IfaceAutoTest.domain.InterfaceDomain;
import com.david.IfaceAutoTest.entity.InterfaceHeader;
import com.david.IfaceAutoTest.entity.ProjectTokenManagement;
import com.david.IfaceAutoTest.mapper.ProjectTokenManagementMapper;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.List;

/**
 * 接口调用工具类
 *
 * @author david
 * @version 1.0
 * @date 2021/12/28 13:59
 */
@Service
public class RestUtil {
    @Resource
    ProjectTokenManagementMapper projectTokenManagementMapper;
    @Resource
    RedisUtils redisUtils;


    //这里是volatile 不是 final 提供可见性并保证不被指令重排 才可以实现线程安全
    private volatile static RestTemplate INSTANCE = null;

    // 私有化构造方法
    private RestUtil() {
    }

    /**
     * 单例实例
     */
    public static RestTemplate getInstance() {
        if (INSTANCE == null) {
            synchronized (RestUtil.class) {
                if (INSTANCE == null) {
                    INSTANCE = new RestTemplate();
                }
            }
        }
        return INSTANCE;
    }

    public static void main(String[] args) {
        System.out.println(RestUtil.getInstance().getForObject("http://localhost:8080/dev/IfaceAutoTest/project/list", String.class));
    }

    public String getResult(InterfaceDomain interfaceDomain) {
        Integer projectId = interfaceDomain.getProjectId();
        List<ProjectTokenManagement> p = projectTokenManagementMapper.selectList(new QueryWrapper<ProjectTokenManagement>().eq("project_id", projectId));
        String tokenFieldName = "";
        if (!p.isEmpty()) {
            tokenFieldName = p.get(0).getTokenFieldName();
        }
        HttpHeaders headers = new HttpHeaders();
        if (interfaceDomain.getInterfaceHeaders().size() > 0) {
            headers.add("Content-Type", "application/json; charset=UTF-8");
            fixHeader(headers, interfaceDomain.getInterfaceHeaders(), tokenFieldName, projectId);
        } else {
            //不设置时会报错。
            headers.add("Content-Type", "application/json; charset=UTF-8");
        }

        if ("POST".equalsIgnoreCase(interfaceDomain.getInterfaceMethod())) {
            if (!headers.isEmpty()) {
                return RestUtil.post(interfaceDomain, headers);
            }
            return RestUtil.post(interfaceDomain);
        } else if ("GET".equalsIgnoreCase(interfaceDomain.getInterfaceMethod())) {
            return RestUtil.get(interfaceDomain);
        }
        return "不在处理方法范围内";
    }

    /**
     * 定制化header 发送post请求
     *
     * @param interfaceDomain 请求URL地址
     */
    public static String post(InterfaceDomain interfaceDomain, HttpHeaders headers) {
        String url = interfaceDomain.getInterfaceRaw();
        String data = interfaceDomain.getInterfaceBodies().get(0).getModeValue();
        HttpEntity<String> formEntity = new HttpEntity<>(data, headers);
        return RestUtil.getInstance().postForObject(url, formEntity, String.class);
    }

    public static String post(InterfaceDomain interfaceDomain) {
        String url = interfaceDomain.getInterfaceRaw();
        String data = interfaceDomain.getInterfaceBodies().get(0).getModeValue();
        HttpEntity<String> formEntity = new HttpEntity<>(data);
        return RestUtil.getInstance().postForObject(url, formEntity, String.class);
    }


    /**
     * get根据url获取对象
     */
    public static String get(InterfaceDomain interfaceDomain) {
        String url = interfaceDomain.getInterfaceRaw();
        return RestUtil.getInstance().getForObject(url, String.class);
    }

    /*
     *  填充header
     */
    public void fixHeader(HttpHeaders headers, List<InterfaceHeader> headerList, String tokenFieldName, Integer projectId) {
        for (InterfaceHeader header : headerList) {
            if (!"".equals(tokenFieldName)&&header.getHeaderValue().replaceAll("\\{", "").replaceAll("}", "").equals(tokenFieldName)) {
                headers.add(header.getHeaderKey(), this.getToken(projectId));
            } else {
                headers.add(header.getHeaderKey(), header.getHeaderValue());
            }
        }
    }

    /*
    获取token
     */
    public String getToken(Integer project_id) {
        ProjectTokenManagement projectTokenManagement = projectTokenManagementMapper.selectOne(new QueryWrapper<ProjectTokenManagement>().select("token_field_name").eq("project_id", project_id));
        return redisUtils.get(project_id + "_" + projectTokenManagement.getTokenFieldName()).toString();
    }
}
